#include "zhi.h"

定义缓冲区方法M(Method)

//判断a和b是否相等
bool 是否相等(Value a, Value b) {
   //类型不同则无须进行后面的比较
   if (a.type != b.type) {
      return false;
   }
   
   //同为数字,比较数值
   if (a.type == 值类型_数字) {
      return a.num == b.num;
   }
   
   //同为对象,若所指的对象是同一个则返回true
   if (a.objHeader == b.objHeader) {
      return true;
   }

   //对象类型不同无须比较
   if (a.objHeader->type != b.objHeader->type) {
      return false;
   }

   //以下处理类型相同的对象
   //若对象同为字符串
   if (a.objHeader->type == 对象类型_字符串) {
      字符串对象S* strA = VALUE_TO_OBJSTR(a);
      字符串对象S* strB = VALUE_TO_OBJSTR(b);
      return (strA->value.长度 == strB->value.长度 &&
	    memcmp(strA->value.start, strB->value.start, strA->value.长度) == 0);
   }

   //若对象同为range
   if (a.objHeader->type == 对象类型_范围) {
      范围对象S* rgA = VALUE_TO_OBJRANGE(a);
      范围对象S* rgB = VALUE_TO_OBJRANGE(b);
      return (rgA->from == rgB->from && rgA->to == rgB->to);
   }

   return false;  //其它对象不可比较
}

//新建一个裸类
Class* 新建一个裸类(虚拟机* 虚拟机S, const char* name, uint32_t fieldNum) {
   Class* class = 分配指定类型的内存块M(虚拟机S, Class); 

   //裸类没有元类
   初始化对象头(虚拟机S, &class->objHeader, 对象类型_类, NULL);
   class->name = 以字符串创建字符串对象(虚拟机S, name, strlen(name));
   class->fieldNum = fieldNum;
   class->superClass = NULL;   //默认没有基类

   将obj作为临时根对象(虚拟机S, (对象头S*)class);
   MethodBufferInit(&class->methods);
   去掉临时根对象(虚拟机S);

   return class;
}

//创建一个类
Class* 新建一个类(虚拟机* 虚拟机S, 字符串对象S* className, uint32_t fieldNum, Class* superClass) {
   //10表示strlen(" metaClass"
   #define MAX_METACLASS_LEN MAX_ID_LEN + 10
   char newClassName[MAX_METACLASS_LEN] = {'\0'};
   #undef MAX_METACLASS_LEN

   memcpy(newClassName, className->value.start, className->value.长度);
   memcpy(newClassName + className->value.长度, " metaclass", 10);

   //先创建子类的meta类
   Class* metaclass = 新建一个裸类(虚拟机S, newClassName, 0);
   metaclass->objHeader.class = 虚拟机S->classOfClass;

   将obj作为临时根对象(虚拟机S, (对象头S*)metaclass);
   //绑定classOfClass为meta类的基类
   //所有类的meta类的基类都是classOfClass
   绑定基类(虚拟机S, metaclass, 虚拟机S->classOfClass);
   
   //最后再创建类
   memcpy(newClassName, className->value.start, className->value.长度);
   newClassName[className->value.长度] = '\0';
   Class* class = 新建一个裸类(虚拟机S, newClassName, fieldNum);
   将obj作为临时根对象(虚拟机S, (对象头S*)class);

   class->objHeader.class = metaclass;
   绑定基类(虚拟机S, class, superClass);

   去掉临时根对象(虚拟机S);   // metaclass
   去掉临时根对象(虚拟机S);   // class
   
   return class;
}

//数字等Value也被视为对象,因此参数为Value.获得对象obj所属的类
Class* 获取对象所属的类(虚拟机* 虚拟机S, Value object) {
   switch (object.type) {
      case 值类型_空:
	 return 虚拟机S->nullClass;
      case 值类型_假:
      case 值类型_真:
	 return 虚拟机S->boolClass;
      case 值类型_数字:
	 return 虚拟机S->numClass;
      case 值类型_对象:
	 return VALUE_TO_OBJ(object)->class;
      default:
	没有达到M(); 
   }
   return NULL;
}
